﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace AramaruForest
{
    class GameItems
    {
        public List<Sprite> Enemies = new List<Sprite>();
        public List<Sprite> Area = new List<Sprite>();
        public List<Sprite> Items = new List<Sprite>();
        public List<Sprite> Projectiles = new List<Sprite>();
        public List<Sprite> MenuItems = new List<Sprite>();

        public Sprite Hero;
        public Sprite Cursor;
        public GameState _gameState;

        public GameItems(GameState gameState)
        {
            _gameState = gameState;
        }

        public void Update(double gameTime, double elapsedTime)
        {
            if (Hero.Velocity.X > 0 || Hero.Velocity.X < 0)
            {
                Hero.CurrentFrame = (int)((gameTime * 8.0) % Hero.NumberOfFrames);
            }
            else
            {
                // Otherwise use frame 0
                Hero.CurrentFrame = 0;
            }

            Hero.Update(gameTime, elapsedTime);

            int remover = 999999;
            int adder = 999999;
            int itterator = 0;
            
            foreach (Sprite tile in Area)
            {
                tile.Update(gameTime, elapsedTime);

                if (tile.trap != null && (Sprite.Collision(Hero, tile) || (tile.trap == "block" && (Hero.Location.X + Hero.Size.Width > tile.Location.X && Hero.Location.X + Hero.Size.Width < tile.Location.X + tile.Size.Width && Hero.Location.Y + Hero.Size.Height >= tile.Location.Y))))
                    if (Trap(tile))
                    {
                        adder = itterator;
                        remover = itterator;
                    }
                if (tile.hp <= 0)
                    remover = itterator;

                if (tile.gravity == true && tile.Velocity.Y != 0)
                {
                    if(Sprite.Collision(tile, Hero) && ((Hero.OldLocation.Y > tile.Location.Y + tile.Size.Height && Hero.Velocity.Y < 0) || (tile.OldLocation.Y + tile.Size.Height < Hero.Location.Y)))
                    {
                        remover = itterator;
                        Hero.Hp -= 4;
                        Hero.Throw(tile);
                        
                    }
                    
                }
                
                itterator++;
            }

            if (adder != 999999)
            {
                Area.Add(Generator.GenerateFallingBlock(_gameState, (int)Area[adder].Location.X, (int)Area[adder].Location.Y));
                Area[Area.Count - 1].JumpStart = _gameState._world._gameTime;
                Area[Area.Count - 1].projectile = false;
            }
            if (remover != 999999)
                Area.RemoveAt(remover);
            foreach (Sprite tile in MenuItems)
            {
                tile.Update(gameTime, elapsedTime);
            }
            
            UpdateItems(gameTime, elapsedTime);
            

            UpdateProjectiles(gameTime, elapsedTime);

            UpdateEnemies(gameTime, elapsedTime);
        }

        private bool Trap(Sprite tile)
        {
            switch (tile.trap)
            {
                case "kunai":
                    if (tile.trapCycler <= 0)
                    {
                        Projectiles.Add(Generator.GenerateDownKunai(_gameState, (int)tile.Location.X, (int)tile.Location.Y));
                        Projectiles.Add(Generator.GenerateDownKunai(_gameState, (int)tile.Location.X + 10, (int)tile.Location.Y));
                        Projectiles.Add(Generator.GenerateDownKunai(_gameState, (int)tile.Location.X + 20, (int)tile.Location.Y));
                        tile.trapCycler = 20;
                    }
                    else
                        tile.trapCycler--;
                    break;

                case "spikes":
                    Enemies.Add(Generator.GenerateSpikes(_gameState, (int)tile.Location.X, (int)tile.Location.Y + 35));
                    Enemies.Add(Generator.GenerateSpikes(_gameState, (int)tile.Location.X + 20, (int)tile.Location.Y + 35));
                    tile.Hp = 0;
                    break;

                case "block":
                    tile.gravity = true;
                    tile.JumpStart = _gameState._world._gameTime;
                    tile.Airborn = true;
                    tile.Velocity.Y = 1;
                    tile.trap = "falling";
                    break;

                case "slow":
                    if (Hero.Velocity.X > 40)
                        Hero.Velocity.X = 40;
                    if (Hero.Velocity.Y < -10)
                        Hero.Velocity.Y = -10;
                    break;

                default:
                    break;

            }
            return false;
        }

        private void UpdateItems(double gameTime, double elapsedTime)
        {
            for (int i = Items.Count - 1; i >= 0; i--)
            {
                if (i < 0 || i >= Items.Count)
                    break;
                Items[i].Update(gameTime, elapsedTime);

                if(Sprite.Collision(Hero, Items[i]))
                {
                    Hero.Hp += Items[i].heals;
                    _gameState._world.mana += Items[i]._kunai;
                    Items.RemoveAt(i);
                    continue;
                }
            }

        }

        private void UpdateEnemies(double gameTime, double elapsedTime)
        {
            for (int i = Enemies.Count - 1; i >= 0; i--)
            {
                if (i < 0 || i >= Enemies.Count)
                    break;
                if (Enemies[i].Hp <= 0)
                {
                    if (Enemies[i].AI == 6)
                        Area.Add(Generator.GenerateWin(_gameState, (int)Enemies[i].Location.X, (int)Enemies[i].Location.Y));
                    Enemies.RemoveAt(i);
                }
                else
                {
                    Enemies[i].Update(gameTime, elapsedTime);

                    if (Sprite.Collision(Enemies[i], Hero))
                    {
                        
                        Hero.Collide(Enemies[i]);

                        if (!Hero.thrown)
                        {
                            Hero.Hp -= Enemies[i].attack;
                            Hero.Throw(Enemies[i]);
                        }
                    }

                    switch (Enemies[i].AI)
                    {
                        case 1:
                            Enemies[i].AI1();
                            break;

                        case 2:
                            Enemies[i].AI2();
                            break;

                        case 3:
                            Enemies[i].AI3();
                            break;

                        case 4:
                            Enemies[i].AI4();
                            break;

                        case 5:
                            Enemies[i].AI5();
                            break;
                        
                        case 6:
                            Enemies[i].AI6();
                            break;

                        default:
                            break;
                    }
                    if (Enemies[i].Velocity.X > 0 || Enemies[i].Velocity.X < 0)
                    {
                        Enemies[i].CurrentFrame = (int)((gameTime * 8.0) % Enemies[i].NumberOfFrames);
                    }
                    else
                    {
                        // Otherwise use frame 0
                        Enemies[i].CurrentFrame = 0;
                    }
                }

            }
        }

        private void UpdateProjectiles(double gameTime, double elapsedTime)
        {
            for (int l = Projectiles.Count - 1; l >= 0; l--)
            {
                if (l < 0)
                    break;
                

                if (Projectiles[l].HeroItem)
                {
                    if (Hero.AttackTime >= 6)
                    {
                        Projectiles[l].Location.X = (int)Hero.Location.X + (int)Hero.Size.Width / 2;
                        Projectiles[l].Location.Y = (int)Hero.Location.Y - Projectiles[l].Size.Height;
                    }
                    else
                    {
                        Projectiles[l].Location.X = Hero.Location.X + Hero.Size.Width - 2;
                        Projectiles[l].Location.Y = Hero.Location.Y + Hero.Size.Height / 2 - 5;
                        Projectiles[l].Flip = Hero.Flip;
                        if (Projectiles[l].Flip)
                        {
                            Projectiles[l].Location.X -= 53;
                        }
                        Projectiles[l].Velocity = Hero.Velocity;
                         
                    }
                    
                    
                }

                Projectiles[l].Update(gameTime, elapsedTime);

                if (!Projectiles[l].HeroItem)
                {
                    if (Sprite.Collision(Hero, Projectiles[l]))
                    {
                        
                        
                            Hero.Hp -= Projectiles[l].attack;
                            Hero.Throw(Projectiles[l]);
                            Projectiles.RemoveAt(l);
                            continue;
                        
                    }
                    else if ((Projectiles[l].OnGround() && !Projectiles[l].groundSurvives) || Projectiles[l].Location.X <= 0 || Projectiles[l].Location.X + Projectiles[l].Size.Width >= _gameState._world.WorldLimits.Width - 1)
                    {
                        Projectiles.RemoveAt(l);
                        continue;
                    }

                }

                if (Projectiles[l].HeroItem)
                {
                    if (Hero.AttackTime >= 6)
                    {
                        Projectiles[l].Location.X = (int)Hero.Location.X + (int)Hero.Size.Width / 2;
                        Projectiles[l].Location.Y = (int)Hero.Location.Y - Projectiles[l].Size.Height;
                    }
                    else
                    {
                        if (Projectiles[l].Size.Height > Projectiles[l].Size.Width)
                        {
                            Projectiles.RemoveAt(l);
                            Sprite s = Generator.GenerateKunai(_gameState, (int)Hero.Location.X + (int)Hero.Size.Width / 2, (int)Hero.Location.Y + (int)Hero.Size.Height / 2, Hero.Flip);
                            s.attack = 3;
                            Projectiles.Add(s);
                            Projectiles[Projectiles.Count() - 1].HeroItem = true;
                        }
                        Projectiles[l].Location.X = Hero.Location.X + Hero.Size.Width - 2;
                        Projectiles[l].Location.Y = Hero.Location.Y + Hero.Size.Height / 2 - 5;
                        Projectiles[l].Flip = Hero.Flip;
                        if (Projectiles[l].Flip)
                        {
                            Projectiles[l].Location.X -= 53;
                        }
                        Projectiles[l].Velocity = Hero.Velocity;
                    }
                    

                }
                foreach (Sprite enemy in Enemies)
                {
                    if (Sprite.Collision(Projectiles[l], enemy) &&  Projectiles[l].AI != 5)
                    {
                        enemy.Hp -= Projectiles[l].attack;
                        Projectiles.RemoveAt(l);
                        break;
                    }


                }



                if (Hero.AttackTime <= 0)
                {
                    Projectiles.RemoveAll(GetWeapons);
                }


            }
        }

        public void Draw(Graphics graphics)
        {

            foreach (Sprite tile in Area)
            {
                tile.Draw(graphics);
            }

            foreach (Sprite item in Items)
            {
                item.Draw(graphics);
            }

            foreach (Sprite projectile in Projectiles)
            {
                projectile.Draw(graphics);
            }

            foreach (Sprite enemy in Enemies)
            {
                enemy.Draw(graphics);
            }
            Hero.Draw(graphics);
        }

        public bool GetWeapons(Sprite s)
        {
            return s.HeroItem;
        }
       
    }
}
